/**
 * 缓存管理工具
 * 提供多层缓存策略：内存缓存、本地存储缓存、会话存储缓存
 */

// 缓存类型枚举
export const CACHE_TYPES = {
  MEMORY: 'memory',
  LOCAL_STORAGE: 'localStorage',
  SESSION_STORAGE: 'sessionStorage'
}

// 默认缓存配置
const DEFAULT_CONFIG = {
  ttl: 5 * 60 * 1000, // 5分钟
  maxSize: 100, // 最大缓存条目数
  type: CACHE_TYPES.MEMORY
}

/**
 * 内存缓存类
 */
class MemoryCache {
  constructor(maxSize = 100) {
    this.cache = new Map()
    this.maxSize = maxSize
    this.accessTimes = new Map() // 记录访问时间，用于LRU
  }

  set(key, value, ttl = DEFAULT_CONFIG.ttl) {
    // 如果缓存已满，删除最久未使用的项
    if (this.cache.size >= this.maxSize) {
      this._evictLRU()
    }

    const expireTime = Date.now() + ttl
    this.cache.set(key, { value, expireTime })
    this.accessTimes.set(key, Date.now())
  }

  get(key) {
    const item = this.cache.get(key)
    if (!item) return null

    // 检查是否过期
    if (Date.now() > item.expireTime) {
      this.delete(key)
      return null
    }

    // 更新访问时间
    this.accessTimes.set(key, Date.now())
    return item.value
  }

  delete(key) {
    this.cache.delete(key)
    this.accessTimes.delete(key)
  }

  clear() {
    this.cache.clear()
    this.accessTimes.clear()
  }

  has(key) {
    const item = this.cache.get(key)
    if (!item) return false
    
    if (Date.now() > item.expireTime) {
      this.delete(key)
      return false
    }
    
    return true
  }

  size() {
    return this.cache.size
  }

  // LRU淘汰策略
  _evictLRU() {
    let oldestKey = null
    let oldestTime = Date.now()

    for (const [key, time] of this.accessTimes) {
      if (time < oldestTime) {
        oldestTime = time
        oldestKey = key
      }
    }

    if (oldestKey) {
      this.delete(oldestKey)
    }
  }
}

/**
 * 存储缓存类（localStorage/sessionStorage）
 */
class StorageCache {
  constructor(storage) {
    this.storage = storage
  }

  set(key, value, ttl = DEFAULT_CONFIG.ttl) {
    try {
      const expireTime = Date.now() + ttl
      const item = {
        value,
        expireTime,
        timestamp: Date.now()
      }
      this.storage.setItem(key, JSON.stringify(item))
    } catch (error) {
      console.warn('Storage cache set failed:', error)
    }
  }

  get(key) {
    try {
      const itemStr = this.storage.getItem(key)
      if (!itemStr) return null

      const item = JSON.parse(itemStr)
      
      // 检查是否过期
      if (Date.now() > item.expireTime) {
        this.delete(key)
        return null
      }

      return item.value
    } catch (error) {
      console.warn('Storage cache get failed:', error)
      return null
    }
  }

  delete(key) {
    try {
      this.storage.removeItem(key)
    } catch (error) {
      console.warn('Storage cache delete failed:', error)
    }
  }

  clear() {
    try {
      this.storage.clear()
    } catch (error) {
      console.warn('Storage cache clear failed:', error)
    }
  }

  has(key) {
    try {
      const itemStr = this.storage.getItem(key)
      if (!itemStr) return false

      const item = JSON.parse(itemStr)
      if (Date.now() > item.expireTime) {
        this.delete(key)
        return false
      }

      return true
    } catch (error) {
      return false
    }
  }

  // 清理过期项
  cleanup() {
    try {
      const keysToDelete = []
      for (let i = 0; i < this.storage.length; i++) {
        const key = this.storage.key(i)
        if (key && !this.has(key)) {
          keysToDelete.push(key)
        }
      }
      keysToDelete.forEach(key => this.delete(key))
    } catch (error) {
      console.warn('Storage cache cleanup failed:', error)
    }
  }
}

/**
 * 统一缓存管理器
 */
class CacheManager {
  constructor() {
    this.memoryCache = new MemoryCache()
    this.localStorageCache = new StorageCache(localStorage)
    this.sessionStorageCache = new StorageCache(sessionStorage)
    
    // 定期清理过期缓存
    this.startCleanupTimer()
  }

  /**
   * 设置缓存
   * @param {string} key - 缓存键
   * @param {any} value - 缓存值
   * @param {Object} options - 缓存选项
   */
  set(key, value, options = {}) {
    const config = { ...DEFAULT_CONFIG, ...options }
    const cache = this._getCache(config.type)
    
    if (cache) {
      cache.set(key, value, config.ttl)
    }
  }

  /**
   * 获取缓存
   * @param {string} key - 缓存键
   * @param {string} type - 缓存类型
   */
  get(key, type = CACHE_TYPES.MEMORY) {
    const cache = this._getCache(type)
    return cache ? cache.get(key) : null
  }

  /**
   * 删除缓存
   * @param {string} key - 缓存键
   * @param {string} type - 缓存类型
   */
  delete(key, type = CACHE_TYPES.MEMORY) {
    const cache = this._getCache(type)
    if (cache) {
      cache.delete(key)
    }
  }

  /**
   * 检查缓存是否存在
   * @param {string} key - 缓存键
   * @param {string} type - 缓存类型
   */
  has(key, type = CACHE_TYPES.MEMORY) {
    const cache = this._getCache(type)
    return cache ? cache.has(key) : false
  }

  /**
   * 清空指定类型的缓存
   * @param {string} type - 缓存类型
   */
  clear(type = CACHE_TYPES.MEMORY) {
    const cache = this._getCache(type)
    if (cache) {
      cache.clear()
    }
  }

  /**
   * 清空所有缓存
   */
  clearAll() {
    this.memoryCache.clear()
    this.localStorageCache.clear()
    this.sessionStorageCache.clear()
  }

  /**
   * 获取缓存统计信息
   */
  getStats() {
    return {
      memory: {
        size: this.memoryCache.size(),
        maxSize: this.memoryCache.maxSize
      },
      localStorage: {
        available: this._isStorageAvailable(localStorage)
      },
      sessionStorage: {
        available: this._isStorageAvailable(sessionStorage)
      }
    }
  }

  /**
   * 获取指定类型的缓存实例
   * @private
   */
  _getCache(type) {
    switch (type) {
      case CACHE_TYPES.MEMORY:
        return this.memoryCache
      case CACHE_TYPES.LOCAL_STORAGE:
        return this.localStorageCache
      case CACHE_TYPES.SESSION_STORAGE:
        return this.sessionStorageCache
      default:
        return this.memoryCache
    }
  }

  /**
   * 检查存储是否可用
   * @private
   */
  _isStorageAvailable(storage) {
    try {
      const test = '__storage_test__'
      storage.setItem(test, test)
      storage.removeItem(test)
      return true
    } catch {
      return false
    }
  }

  /**
   * 启动清理定时器
   * @private
   */
  startCleanupTimer() {
    // 每10分钟清理一次过期缓存
    setInterval(() => {
      this.localStorageCache.cleanup()
      this.sessionStorageCache.cleanup()
    }, 10 * 60 * 1000)
  }
}

// 创建全局缓存管理器实例
export const cacheManager = new CacheManager()

// 导出缓存装饰器
export function cached(options = {}) {
  return function(target, propertyKey, descriptor) {
    const originalMethod = descriptor.value
    
    descriptor.value = async function(...args) {
      const cacheKey = `${propertyKey}_${JSON.stringify(args)}`
      
      // 尝试从缓存获取
      const cachedResult = cacheManager.get(cacheKey, options.type)
      if (cachedResult !== null) {
        return cachedResult
      }
      
      // 执行原方法并缓存结果
      const result = await originalMethod.apply(this, args)
      cacheManager.set(cacheKey, result, options)
      
      return result
    }
    
    return descriptor
  }
}

export default cacheManager